package com.datareport.config.datasource;

import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * 多数据源配置类
 * 根据数据库设计文档配置三个数据库：
 * 1. business_db - 业务数据库
 * 2. statistics_db - 统计结果库  
 * 3. system_db - 系统配置库
 */
@Slf4j
@Configuration
@EnableTransactionManagement
@MapperScan(basePackages = "com.datareport.repository", sqlSessionFactoryRef = "sqlSessionFactory")
public class MultiDataSourceConfig {

    /**
     * 业务数据库数据源配置
     */
    @Bean("businessDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.business")
    public DataSource businessDataSource() {
        log.info("创建业务数据库数据源");
        return new HikariDataSource();
    }

    /**
     * 统计结果库数据源配置
     */
    @Bean("statisticsDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.statistics")
    public DataSource statisticsDataSource() {
        log.info("创建统计结果库数据源");
        return new HikariDataSource();
    }

    /**
     * 系统配置库数据源配置
     */
    @Bean("systemDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.system")
    public DataSource systemDataSource() {
        log.info("创建系统配置库数据源");
        return new HikariDataSource();
    }

    /**
     * 动态数据源配置
     * 设置默认数据源为业务数据库
     */
    @Primary
    @Bean("dynamicDataSource")
    public DataSource dynamicDataSource(
            @Qualifier("businessDataSource") DataSource businessDataSource,
            @Qualifier("statisticsDataSource") DataSource statisticsDataSource,
            @Qualifier("systemDataSource") DataSource systemDataSource) {
        
        log.info("创建动态数据源");
        
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        
        // 配置数据源映射
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put(DataSourceContextHolder.DataSourceType.BUSINESS_DB.getCode(), businessDataSource);
        targetDataSources.put(DataSourceContextHolder.DataSourceType.STATISTICS_DB.getCode(), statisticsDataSource);
        targetDataSources.put(DataSourceContextHolder.DataSourceType.SYSTEM_DB.getCode(), systemDataSource);
        
        dynamicDataSource.setTargetDataSources(targetDataSources);
        
        // 设置默认数据源
        dynamicDataSource.setDefaultTargetDataSource(businessDataSource);
        
        log.info("动态数据源配置完成，默认数据源: {}", DataSourceContextHolder.DataSourceType.BUSINESS_DB.getCode());
        return dynamicDataSource;
    }

    /**
     * SQL会话工厂配置
     */
    @Primary
    @Bean("sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(
            @Qualifier("dynamicDataSource") DataSource dynamicDataSource,
            MybatisPlusInterceptor mybatisPlusInterceptor) throws Exception {
        
        log.info("创建SQL会话工厂");
        
        MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean();
        sessionFactory.setDataSource(dynamicDataSource);
        
        // MyBatis配置
        MybatisConfiguration configuration = new MybatisConfiguration();
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.setLogImpl(StdOutImpl.class);
        sessionFactory.setConfiguration(configuration);
        
        // 设置Mapper XML文件位置
        sessionFactory.setMapperLocations(
            new PathMatchingResourcePatternResolver()
                .getResources("classpath:mapper/*.xml")
        );
        
        // 设置实体类包路径
        sessionFactory.setTypeAliasesPackage("com.datareport.domain.entity");
        
        // 添加MyBatis-Plus插件
        sessionFactory.setPlugins(mybatisPlusInterceptor);
        
        return sessionFactory.getObject();
    }

    /**
     * 事务管理器配置
     */
    @Primary
    @Bean("transactionManager")
    public PlatformTransactionManager transactionManager(
            @Qualifier("dynamicDataSource") DataSource dynamicDataSource) {
        log.info("创建事务管理器");
        return new DataSourceTransactionManager(dynamicDataSource);
    }

    /**
     * JdbcTemplate配置
     */
    @Bean("jdbcTemplate")
    public JdbcTemplate jdbcTemplate(@Qualifier("dynamicDataSource") DataSource dynamicDataSource) {
        log.info("创建JdbcTemplate");
        return new JdbcTemplate(dynamicDataSource);
    }

    /**
     * 业务数据库JdbcTemplate
     */
    @Bean("businessJdbcTemplate")
    public JdbcTemplate businessJdbcTemplate(@Qualifier("businessDataSource") DataSource businessDataSource) {
        log.info("创建业务数据库JdbcTemplate");
        return new JdbcTemplate(businessDataSource);
    }

    /**
     * 统计结果库JdbcTemplate
     */
    @Bean("statisticsJdbcTemplate")
    public JdbcTemplate statisticsJdbcTemplate(@Qualifier("statisticsDataSource") DataSource statisticsDataSource) {
        log.info("创建统计结果库JdbcTemplate");
        return new JdbcTemplate(statisticsDataSource);
    }

    /**
     * 系统配置库JdbcTemplate
     */
    @Bean("systemJdbcTemplate")
    public JdbcTemplate systemJdbcTemplate(@Qualifier("systemDataSource") DataSource systemDataSource) {
        log.info("创建系统配置库JdbcTemplate");
        return new JdbcTemplate(systemDataSource);
    }
}